package jp.co.toshiba.ffsa.service.csde;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.security.Key;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;

import jp.co.toshiba.ffsa.service.common.ConstantValue;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.framework.beans.util.BeanMap;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.struts.util.MessageResourcesUtil;
import org.seasar.struts.util.ResponseUtil;

/**
 * 設計I/F - プロジェクト詳細 ビジネスロジック
 * @author npc
 */
public class Csde301Service {

    /** プロジェクトID */
    private String projectId;

    /**
     * プロジェクト詳細情報取得
     * @return プロジェクト詳細情報
     * @throws Exception
     */
    public List<BeanMap> getProjectDetail() throws Exception {

        // S2Container初期化
        SingletonS2ContainerFactory.init();

        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);

        try{
            // プロジェクト詳細情報取得
            List<BeanMap> resultList = jdbcManager.selectBySqlFile( BeanMap.class
                                                                  , "data/selectProjectDetail.sql"
                                                                  , this.projectId
                                                                  ).getResultList();

            return resultList;

        }catch(Exception e){
            throw e;
        }
    }

    /**
     * ファイル情報取得
     * @return ファイル情報
     * @throws Exception
     */
    public List<BeanMap> getFileList(String inOut) throws Exception {

        // S2Container初期化
        SingletonS2ContainerFactory.init();

        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);

        try{
            // 検索条件
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("project_id", this.projectId);
            param.put("in_out" , inOut);

            // ファイル情報取得
            List<BeanMap> resultList = jdbcManager.selectBySqlFile( BeanMap.class
                                                                  , "data/selectFileList.sql"
                                                                  , param
                                                                  ).getResultList();

            return resultList;

        }catch(Exception e){
            throw e;
        }
    }

    /**
     * 設計書ダウンロード
     * @param fileName 設計書ファイル
     * @return true:ダウンロード成功 false：ダウンロード失敗
     * @throws Exception
     */
    public boolean downloadFile(String fileName) throws Exception {

        // ダウンロード処理チェック
        boolean successFlag = false;

        HttpServletResponse response = ResponseUtil.getResponse();

        // ファイルパス
        File file = new File(fileName);

        FileInputStream   fis = null;
        CipherInputStream cis = null;
        InputStream       in  = null;
        OutputStream      out = null;

        try {
            ResponseUtil.getResponse().setContentType("application/octet-stream");
            ResponseUtil.getResponse().setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), MessageResourcesUtil.getMessage("charset")));

            Key key = new SecretKeySpec(DigestUtils.sha256(ConstantValue.key), "AES");
            fis = new FileInputStream(file);
            byte[] iv = new byte[16];
            fis.read(iv);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, key, ivspec);
            cis = new CipherInputStream(fis, cipher);

            in = new BufferedInputStream(cis);
            out = ResponseUtil.getResponse().getOutputStream();
            int data;
            byte[] b = new byte[1024];
            while ((data = in.read(b, 0, 1024)) != -1) {
                out.write(b, 0, data);
            }

            successFlag = true;

        } catch (Exception e) {
            successFlag = false;
            response.reset();
            throw e;

        } finally {
            IOUtils.closeQuietly(fis);
            IOUtils.closeQuietly(cis);
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
        }

        return successFlag;
    }

    /**
     * プロジェクトIDをセットする
     * @param projectId
     */
    public void setProjectId(String projectId){this.projectId = projectId;}
}